/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package multiversiontechnicaldocumentation;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Multiversion technical document writer to HTML.
 * 
 * 
 * @author VadimBaitoiu
 */
public class HTMLWriter extends Writer {

    public static final String DEFAULT_STYLE = "<style media=\"screen\" type=\"text/css\">"
            + "body {font-family:Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size:12px}"
            + ".logicalsection {padding:3px 0px 6px 50px;}"
            + ".logicalsectiontitle {font-weight:bold;padding:9px 0px 3px 0px;}"
            + ".error {color:red;}"
            + "</style>";

    /**
     *
     * @param document
     * @throws IOException
     */
    @Override
    public void write(Document document) throws IOException {
        this.out.write("<!DOCTYPE html>" + NEWLINE
                + "<html>" + NEWLINE);

        Document.Version documentVersion = document.getCurrentVersion();
        if (document.getCurrentVersion() != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(DOCUMENT_VERSION_TIME_FORMAT);
            Date date = new Date();
            this.out.write("<head>" + NEWLINE
                    + "<meta charset=\"UTF-8\">" + NEWLINE);
            date.setTime(documentVersion.getTime());
            String s = sdf.format(date) + ' ' + documentVersion.getTitle();
            this.out.write("<title>" + s + "</title>" + NEWLINE
                    + DEFAULT_STYLE + NEWLINE
                    + "</head>" + NEWLINE);
            this.out.write("<body>" + NEWLINE);

            this.out.write("<div style=\"width: 800px\">" + NEWLINE); // width limiter

            Document.LogicalSection root = documentVersion.getRoot();
            // root logical section is implicit --> do not write logical section command
            Object content = root.getContent();
            if (content instanceof Document.LogicalSection) {
                // handle child logical section
                Document.LogicalSection i = (Document.LogicalSection) content;
                while (i != null) {
                    write(i, 1);
                    i = i.getNext();
                }
            } else {
                s = "NULL";
                if (content != null) {
                    s = content.getClass().getName();
                }
                this.out.write("<div class=\"error\">Invalid logical section content type: " + s + "</div>");
            }
        } else {
            this.out.write("<body>" + NEWLINE);
            this.out.write("<div class=\"error\">Current document version is undefined.</div>" + NEWLINE);
        }

        this.out.write("</div>" + NEWLINE); // width limiter
        this.out.write(NEWLINE + "</body>" + NEWLINE + "</html>" + NEWLINE);
    }

    /**
     *
     * @param logicalSection
     * @param indentationLevel 1..8 (see Document.MAX_DEPTH)
     * @throws IOException
     */
    private void write(Document.LogicalSection logicalSection, int indentationLevel) throws IOException {
        if (indentationLevel > Document.MAX_DEPTH) {
            this.out.write("ERROR Maximum document depth exceeded");
            return;
        }

        this.out.write(NEWLINE);
        this.out.write("<div class=\"logicalsection\">" + NEWLINE);
        String s = logicalSection.getTitle();
        this.out.write("<div class=\"logicalsectiontitle\">" + s + "</div>" + NEWLINE);

        this.out.write("<div class=\"logicalsectioncontent\">" + NEWLINE);

        Object content = logicalSection.getContent();
        if (content == null) {
            // 
        } else {
            if (content instanceof Document.LogicalSection) {
                // handle child logical section
                Document.LogicalSection i = (Document.LogicalSection) content;
                while (i != null) {
                    write(i, indentationLevel + 1);
                    i = i.getNext();
                }
            } else {
                if (content instanceof String) {
                    // handle text
                    s = (String) content;
                    this.out.write(s);
                } else {
                    s = content.getClass().getName();
                    this.out.write("<div class=\"error\">Invalid logical section content type: " + s + "</div>");
                }
            }
        }

        this.out.write("</div>" + NEWLINE); // logical section content
        this.out.write("</div>" + NEWLINE); // logical section
    }
}
